package admin

import (
	"context"
	"github.com/dustin/go-humanize"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gfile"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
	"miaoyu/internal/dao"
	"miaoyu/internal/model/admin"
	"miaoyu/internal/model/entity"
	"miaoyu/internal/service"
	"path"
	"strings"
)

type sFile struct {
}

func init() {
	service.RegisterFile(NewFile())
}

func NewFile() *sFile {

	return &sFile{}
}

func (s *sFile) checkFile(ctx context.Context, check string, in *admin.FileUploadInput) error {
	config, _ := g.Cfg().Get(ctx, check)

	var options admin.UploadOption

	confErr := gconv.Scan(config, &options)
	if confErr != nil {
		g.Log().Error(ctx, "upload init error")
		return confErr
	}
	if options.RootPath == "" {
		return gerror.New("上传文件路径配置不存在")
	}
	dateDirName := gtime.Now().Format("Ymd")
	uploadPath := gfile.Join(options.BasePath, options.SubPath, dateDirName)
	in.UploadPath = uploadPath
	in.AbsUploadPath = gfile.Join(options.RootPath, in.UploadPath)
	if int64(options.MaxSize) < in.File.Size {

		return gerror.New("文件大小应限制在" + humanize.Bytes(uint64(options.MaxSize)))
	}
	var ext = path.Ext(in.File.Filename)
	in.Ext = ext

	if strings.Index(options.AllowFiles, ext) == -1 {
		return gerror.New("请选择" + options.AllowFiles + "的文件格式！")
	}

	return nil
}

// UploadImg 本地上传接口
func (s *sFile) UploadImg(ctx context.Context, in admin.FileUploadInput) (*admin.FileUploadOutput, error) {

	//检查文件上传设置
	checkRes := s.checkFile(ctx, "upload.default", &in)
	if checkRes != nil {
		return nil, checkRes
	}

	if in.Name != "" {
		in.File.Filename = in.Name
	}
	fileName, err := in.File.Save(in.AbsUploadPath, in.RandomName)
	if err != nil {
		return nil, err
	}
	url := in.UploadPath + gfile.Separator + fileName
	// 记录到数据表
	data := entity.CmsAttachment{
		Name:   in.File.Filename,
		Module: in.Module,
		Path:   gstr.Replace(in.UploadPath, "\\", "/"),
		Url:    gstr.Replace(url, "\\", "/"),
		Uid:    service.Auth().GetIdentity(ctx),
		Size:   gconv.Uint(in.File.Size),
		Ext:    in.Ext,
	}

	resId, err := dao.CmsAttachment.AddAndId(ctx, data)
	if err != nil {
		return nil, err
	}

	return &admin.FileUploadOutput{
		Id:   uint(resId),
		Name: data.Name,
		Path: data.Path,
		Url:  data.Url,
	}, nil
}

// UploadFile 本地上传接口
func (s *sFile) UploadFile(ctx context.Context, in admin.FileUploadInput) (*admin.FileUploadOutput, error) {

	//检查文件上传设置
	checkRes := s.checkFile(ctx, "upload.file", &in)
	if checkRes != nil {
		return nil, checkRes
	}

	if in.Name != "" {
		in.File.Filename = in.Name
	}
	fileName, err := in.File.Save(in.AbsUploadPath, in.RandomName)
	if err != nil {
		return nil, err
	}
	url := in.UploadPath + gfile.Separator + fileName
	// 记录到数据表
	data := entity.CmsAttachment{
		Name:   in.File.Filename,
		Module: in.Module,
		Path:   gstr.Replace(in.UploadPath, "\\", "/"),
		Url:    gstr.Replace(url, "\\", "/"),
		Uid:    service.Auth().GetIdentity(ctx),
		Size:   gconv.Uint(in.File.Size),
		Ext:    in.Ext,
	}

	resId, err := dao.CmsAttachment.AddAndId(ctx, data)
	if err != nil {
		return nil, err
	}

	return &admin.FileUploadOutput{
		Id:   uint(resId),
		Name: data.Name,
		Path: data.Path,
		Url:  data.Url,
	}, nil
}
